package com.qiangesoft.im.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qiangesoft.im.auth.UserUtil;
import com.qiangesoft.im.entity.ImGroup;
import com.qiangesoft.im.entity.ImGroupUser;
import com.qiangesoft.im.entity.SysUser;
import com.qiangesoft.im.exception.ServiceException;
import com.qiangesoft.im.mapper.ImGroupMapper;
import com.qiangesoft.im.pojo.dto.ImGroupDTO;
import com.qiangesoft.im.pojo.dto.ImGroupMasterDTO;
import com.qiangesoft.im.pojo.vo.ImGroupInfoVO;
import com.qiangesoft.im.pojo.vo.ImGroupVO;
import com.qiangesoft.im.pojo.vo.SysUserVo;
import com.qiangesoft.im.service.IImGroupService;
import com.qiangesoft.im.service.IImGroupUserService;
import com.qiangesoft.im.service.ISysUserService;
import com.qiangesoft.im.util.IdSplitUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 群组 服务实现类
 * </p>
 *
 * @author qiangesoft
 * @date 2024-02-07
 */
@Service
public class ImGroupServiceImpl extends ServiceImpl<ImGroupMapper, ImGroup> implements IImGroupService {

    @Autowired
    private IImGroupUserService groupUserService;
    @Autowired
    private ISysUserService sysUserService;

    @Transactional(rollbackFor = RuntimeException.class)
    @Override
    public void addGroup(ImGroupDTO groupDTO) {
        Long userId = UserUtil.getUserId();

        ImGroup group = new ImGroup();
        group.setName(groupDTO.getName());
        group.setAvatar(groupDTO.getAvatar());
        group.setMaster(userId);
        group.setManager(IdSplitUtil.listToStr(groupDTO.getManager()));
        group.setNotice(groupDTO.getNotice());
        group.setRemark(groupDTO.getRemark());
        group.setDelFlag(false);
        baseMapper.insert(group);

        // 群成员
        List<ImGroupUser> groupUserList = new ArrayList<>();
        List<Long> memberIdList = groupDTO.getMemberIdList();
        if (!memberIdList.contains(userId)) {
            memberIdList.add(userId);
        }
        for (Long memberId : memberIdList) {
            ImGroupUser groupUser = new ImGroupUser();
            groupUser.setGroupId(group.getId());
            groupUser.setUserId(memberId);
            groupUser.setDelFlag(false);
            groupUserList.add(groupUser);
        }
        groupUserService.saveBatch(groupUserList);
    }

    @Override
    public void removeGroup(Long id) {
        LambdaUpdateWrapper<ImGroup> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(ImGroup::getId, id)
                .set(ImGroup::getDelFlag, true);
        baseMapper.update(null, updateWrapper);
    }

    @Override
    public void updateGroup(Long id, ImGroupDTO groupDTO) {
        ImGroup group = this.validateGroup(id);
        if (group.getDelFlag()) {
            throw new ServiceException("群组已解散！");
        }

        group.setName(groupDTO.getName());
        group.setAvatar(groupDTO.getAvatar());
        group.setManager(IdSplitUtil.listToStr(groupDTO.getManager()));
        group.setNotice(groupDTO.getNotice());
        group.setRemark(groupDTO.getRemark());
        baseMapper.updateById(group);
    }

    @Override
    public List<ImGroupVO> listGroup(String keyword) {
        LambdaQueryWrapper<ImGroup> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(StringUtils.isNotBlank(keyword), ImGroup::getRemark, keyword)
                .eq(ImGroup::getDelFlag, false);
        List<ImGroup> groupList = baseMapper.selectList(queryWrapper);
        List<ImGroupVO> groupVOList = new ArrayList<>();
        if (CollectionUtils.isEmpty(groupList)) {
            return groupVOList;
        }

        for (ImGroup group : groupList) {
            ImGroupVO groupVO = new ImGroupVO();
            groupVO.setId(group.getId());
            groupVO.setName(group.getName());
            groupVO.setAvatar(group.getAvatar());
            groupVO.setRemark(group.getRemark());
            groupVO.setCreateTime(group.getCreateTime().getTime());
            groupVOList.add(groupVO);
        }
        return groupVOList;
    }

    @Override
    public ImGroupInfoVO getGroupInfo(Long id) {
        ImGroup group = this.validateGroup(id);

        ImGroupInfoVO vo = new ImGroupInfoVO();
        vo.setId(group.getId());
        vo.setName(group.getName());
        vo.setAvatar(group.getAvatar());
        vo.setNotice(group.getNotice());
        vo.setRemark(group.getRemark());
        vo.setCreateTime(group.getCreateTime().getTime());

        // 群主
        Long masterId = group.getMaster();
        if (masterId != null) {
            SysUser master = sysUserService.getById(masterId);
            if (master != null) {
                SysUserVo masterVo = SysUserVo.fromEntity(master);
                vo.setMaster(masterVo);
            }
        }

        // 群管理
        String manager = group.getManager();
        List<Long> managerIdList = IdSplitUtil.strToList(manager);
        if (!CollectionUtils.isEmpty(managerIdList)) {
            List<SysUserVo> managerUserList = sysUserService.listByIds(managerIdList).stream().map(SysUserVo::fromEntity).collect(Collectors.toList());
            vo.setManagerList(managerUserList);
        }

        // 群成员
        List<SysUserVo> userVoList = new ArrayList<>();
        LambdaQueryWrapper<ImGroupUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ImGroupUser::getGroupId, id)
                .eq(ImGroupUser::getDelFlag, false);
        List<ImGroupUser> groupUserList = groupUserService.list(queryWrapper);
        if (CollectionUtils.isEmpty(groupUserList)) {
            vo.setMemberList(userVoList);
            return vo;
        }

        List<Long> userIdList = groupUserList.stream().map(ImGroupUser::getUserId).collect(Collectors.toList());
        Map<Long, SysUserVo> sysUserVOMap = sysUserService.listByIds(userIdList).stream().map(SysUserVo::fromEntity).collect(Collectors.toMap(SysUserVo::getId, sysUserVo -> sysUserVo));
        for (ImGroupUser groupUser : groupUserList) {
            SysUserVo sysUserVo = sysUserVOMap.get(groupUser.getUserId());
            if (sysUserVo != null) {
                userVoList.add(sysUserVo);
            }
        }
        vo.setMemberList(userVoList);
        return vo;
    }

    @Override
    public void updateMaster(ImGroupMasterDTO groupMasterDTO) {
        Long id = groupMasterDTO.getId();
        ImGroup group = this.validateGroup(id);
        if (group.getDelFlag()) {
            throw new ServiceException("群组已解散！");
        }

        LambdaUpdateWrapper<ImGroup> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(ImGroup::getId, id)
                .set(ImGroup::getMaster, groupMasterDTO.getMaster());
        baseMapper.update(null, updateWrapper);
    }

    @Override
    public ImGroup validateGroup(Long id) {
        ImGroup group = baseMapper.selectById(id);
        if (group == null) {
            throw new ServiceException("群组不存在");
        }
        return group;
    }
}
